#ifndef __ASYNC_MESSAGE_H__
#define __ASYNC_MESSAGE_H__

#include <functional>
#include <memory>
#include <vector>
#include <mutex>
#include <queue>

#include "eventloop.h"

namespace Gazella {

struct IAsyncMessage: public std::enable_shared_from_this<IAsyncMessage> {
    virtual ~IAsyncMessage() = default;

    std::shared_ptr<IAsyncMessage> get_this() {
        return shared_from_this();
    }
};

typedef std::function<void(const std::shared_ptr<IAsyncMessage>&)> async_notify_func_t;

class GzAsyncMessage {
public:
    GzAsyncMessage();
    ~GzAsyncMessage();

    void connect(async_notify_func_t func);
    void send(const std::shared_ptr<IAsyncMessage>& async_message);

private:
    void __async_watcher(ev::async& watcher, int revents);

private:
    ev::async m_watcher;
    std::mutex m_async_lock;
    std::queue<std::shared_ptr<IAsyncMessage>> m_async_message_queue;

    std::mutex m_notify_lock;
    std::vector<async_notify_func_t> m_notifies; 
};
}

#endif